Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/service locator #7

Merged

Conversation

falkenhawk
Copy link
Member

@falkenhawk falkenhawk commented Apr 30, 2019

ServiceLocator

  • Serving "lazy" dependencies for classes using ServiceSubscriberInterface.
  • A ServiceSubscriber exposes its dependencies via static getSubscribedServices() method.
  • A ServiceLocator instance could then be injected into a class via constructor or a property - the instance would be already configured with dependences read from getSubscribedServices(), but the dependences won't be instantiated until first get - that's how "laziness" is introduced
  • DI\Definition\Reference checks if it's a ServiceLocator entry by comparing its name with DI\Definition\Reference::$serviceLocatorClass
  • Reference definitions are passed with additional parameter - $requestingName which generally points to name of the class which implements ServiceSubscriberInterface - to resolve ServiceLocator for that class
  • Suggested as a lightweight alternative for heavyweight proxies from ocramius/proxy-manager

note:

Usage:

class MyClass implements ServiceSubscriberInterface
{
    /**
     * @var ServiceLocator
     */
    protected $serviceLocator;

    /**
     * @param ServiceLocator $serviceLocator
     */
    public function __construct(ServiceLocator $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    /**
     * Lazy instantiate heavy dependencies on-demand
     */
    public static function getSubscribedServices(): array
    {
        return [
            SomeClass::class,
            'heavyDependency' => HeavyService::class,
        ];
    }

    public function doOperation()
    {
        $someClass = $this->serviceLocator->get(SomeClass::class);
        return $someClass->doSomething();
    }

    public function getSomethingFromThatHeavyDependency()
    {
        // this method may be rarely used, and it might be good idea to skip resolving the dependency every time during instantiation for performance reasons
        return $this->serviceLocator->get('heavyDependency')->getSomething();
    }
}

- Serving "lazy" dependencies for classes using ServiceSubscriberInterface.
- A ServiceSubscriber exposes its dependencies via static getSubscribedServices() method.
- A ServiceLocator instance could then be injected into a class via constructor or a property - the instance would be already configured with dependences read from getSubscribedServices(), but the dependences won't be instantiated until first get - that's how "laziness" is introduced
- DI\Definition\Reference checks if it's a ServiceLocator entry by comparing its name with DI\Definition\Reference::$serviceLocatorClass
- Reference definitions are passed with additional parameter - $requestingName which generally points to name of the class which implements ServiceSubscriberInterface - to resolve ServiceLocator for that class
- Suggested as a lightweight alternative for heavyweight proxies from ocramius/proxy-manager
@falkenhawk falkenhawk self-assigned this Apr 30, 2019
- the method may be used only before a locator instance is created - to avoid ambiguous situations
- create method refactored - a locator instance will be returned if already created, only if passed services match, otherwise an exception will be thrown
- resolve and isResolvable will check if getSubscribedServices method exists on given class
+ added the same method_exists check as in ServiceLocatorDefinition
@falkenhawk falkenhawk force-pushed the feature/service-locator branch from d118c58 to 2a10132 Compare May 30, 2019 13:59
@falkenhawk falkenhawk marked this pull request as ready for review May 30, 2019 14:12
@falkenhawk falkenhawk merged commit 0fe5cce into feature/annotations-autowiring-options May 30, 2019
falkenhawk added a commit that referenced this pull request May 30, 2019
@falkenhawk falkenhawk deleted the feature/service-locator branch January 20, 2021 16:16
partikus added a commit that referenced this pull request Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant